VintaSoft Imaging .NET SDK 12.4: Documentation for .NET developer
Vintasoft.Imaging.Pdf Namespace / PdfFontManager Class / CreateFontSubset Methods / CreateFontSubset(PdfFont,PdfTextSymbol[],Int32,Boolean,PdfTextSymbol[]) Method
Syntax Exceptions Example Requirements SeeAlso
In This Topic
    CreateFontSubset(PdfFont,PdfTextSymbol[],Int32,Boolean,PdfTextSymbol[]) Method (PdfFontManager)
    In This Topic
    Creates new PDF font, which contains the specified set of text symbols.
    Syntax
    'Declaration
    
    Public Overloads Function CreateFontSubset( _
    ByVal sourceFont
    Source PDF font.
    As Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont, _
    ByVal symbols
    A set of text symbols from source PDF font. Text symbols are ordered as they should be stored in new PDF font.
    () As Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol, _
    ByVal symbolCodeSize
    Size, in bytes, of code symbol of new PDF font.
    As System.Int32, _
    ByVal addEncoding
    A value indicating whether the information about Unicode codes of symbols must be added to new PDF font.
    As Boolean, _
    ByRef newSymbols
    An array of text symbols of newly created PDF font. Each symbol in array newSymbols corresponds to the symbol, with the same index, in array symbols.
    () As Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol _
    ) As Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont

    Parameters

    sourceFont
    Source PDF font.
    symbols
    A set of text symbols from source PDF font. Text symbols are ordered as they should be stored in new PDF font.
    symbolCodeSize
    Size, in bytes, of code symbol of new PDF font.
    addEncoding
    A value indicating whether the information about Unicode codes of symbols must be added to new PDF font.
    newSymbols
    An array of text symbols of newly created PDF font. Each symbol in array newSymbols corresponds to the symbol, with the same index, in array symbols.

    Return Value

    New PDF font.
    Exceptions
    ExceptionDescription
    Thrown if sourceFont or symbols is null.
    Thrown if array of symbols is empty -or- original font is not fully defined.
    Thrown if array of symbols contains symbols from another font.
    Thrown if symbolCodeSize is 0 or exceeds 2 -or- number of symbols exceeds maximum number that can be encoded by symbolCodeSize.
    Thrown if subsetting of sourceFont is not supported.
    Example

    Here is an example that shows how to create a PDF font, which is based on a subset of font symbols:

    
    ''' <summary>
    ''' Creates CID font, which is based on the specified TrueType font,
    ''' creates a PDF font, which is a minimal subset necessary for drawing specified text, and
    ''' creates a PDF document with the specified text and font.
    ''' </summary>
    ''' <param name="pdfFilename">The name of file, where PDF document must be saved.</param>
    ''' <param name="trueTypeFontFilename">The filename of TrueType font.</param>
    ''' <param name="text">The text to draw on PDF page.</param>
    Public Shared Sub CreatePdfFontSubset(pdfFilename As String, trueTypeFontFilename As String, text As String)
        ' list of unique necessary characters to render specified text
        Dim usedChars As New System.Collections.Generic.List(Of Char)()
        For i As Integer = 0 To text.Length - 1
            If Not usedChars.Contains(text(i)) Then
                usedChars.Add(text(i))
            End If
        Next
    
        ' create new PDF document
        Using document As New Vintasoft.Imaging.Pdf.PdfDocument()
            ' create initial PDF font
            Dim sourceFont As Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont = document.FontManager.CreateCIDFontFromTrueTypeFont(trueTypeFontFilename)
            ' get symbols of the font
            Dim fontSymbols As Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol() = Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol.GetFontSymbols(sourceFont)
            ' list of PDF font symbols, which are necessary for rendering the specified text
            Dim necessarySymbols As New System.Collections.Generic.List(Of Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol)()
            For i As Integer = 0 To fontSymbols.Length - 1
                ' get next PDF font symbol
                Dim fontSymbol As Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol = fontSymbols(i)
                ' determine if symbol is used in text
                For j As Integer = 0 To usedChars.Count - 1
                    If fontSymbol.Symbol = usedChars(j) Then
                        necessarySymbols.Add(fontSymbol)
                        Exit For
                    End If
                Next
    
                If necessarySymbols.Count = usedChars.Count Then
                    ' optimization: we have all necessary symbols and can go on
                    Exit For
                End If
            Next
    
            ' determine symbol code size in bytes
            Dim symbolCodeSizeInBytes As Integer = If(sourceFont.FontType = Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFontType.Type0, 2, 1)
            Dim newSymbols As Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol() = Nothing
            ' create font subset
            Dim pdfFontSubset As Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont = document.FontManager.CreateFontSubset(sourceFont, necessarySymbols.ToArray(), symbolCodeSizeInBytes, True, newSymbols)
    
            ' add PDF page
            Dim page As Vintasoft.Imaging.Pdf.Tree.PdfPage = document.Pages.Add(Vintasoft.Imaging.PaperSizeKind.A4)
            ' open PDF graphics
            Using graphics As Vintasoft.Imaging.Pdf.Drawing.PdfGraphics = page.GetGraphics()
                Dim brush As New Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.Black)
                Dim location As New System.Drawing.PointF(30, page.Size.Height - 150)
                ' draw text using created font
                graphics.DrawString(text, pdfFontSubset, 18F, brush, location)
            End Using
            ' pack PDF document to the specified location
            document.Pack(pdfFilename)
        End Using
    End Sub
    
    
    
    /// <summary>
    /// Creates CID font, which is based on the specified TrueType font,
    /// creates a PDF font, which is a minimal subset necessary for drawing specified text, and
    /// creates a PDF document with the specified text and font.
    /// </summary>
    /// <param name="pdfFilename">The name of file, where PDF document must be saved.</param>
    /// <param name="trueTypeFontFilename">The filename of TrueType font.</param>
    /// <param name="text">The text to draw on PDF page.</param>
    public static void CreatePdfFontSubset(string pdfFilename, string trueTypeFontFilename, string text)
    {
        // list of unique necessary characters to render specified text
        System.Collections.Generic.List<char> usedChars = 
            new System.Collections.Generic.List<char>();
        for (int i = 0; i < text.Length; i++)
        {
            if (!usedChars.Contains(text[i]))
                usedChars.Add(text[i]);
        }
    
        // create new PDF document
        using (Vintasoft.Imaging.Pdf.PdfDocument document = new Vintasoft.Imaging.Pdf.PdfDocument())
        {
            // create initial PDF font
            Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont sourceFont = 
                document.FontManager.CreateCIDFontFromTrueTypeFont(trueTypeFontFilename);
            // get symbols of the font
            Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol[] fontSymbols = 
                Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol.GetFontSymbols(sourceFont);
            // list of PDF font symbols, which are necessary for rendering the specified text
            System.Collections.Generic.List<Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol> necessarySymbols = 
                new System.Collections.Generic.List<Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol>();
            for (int i = 0; i < fontSymbols.Length; i++)
            {
                // get next PDF font symbol
                Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol fontSymbol = fontSymbols[i];
                // determine if symbol is used in text
                for (int j = 0; j < usedChars.Count; j++)
                {
                    if (fontSymbol.Symbol == usedChars[j])
                    {
                        necessarySymbols.Add(fontSymbol);
                        break;
                    }
                }
    
                if (necessarySymbols.Count == usedChars.Count)
                {
                    // optimization: we have all necessary symbols and can go on
                    break;
                }
            }
    
            // determine symbol code size in bytes
            int symbolCodeSizeInBytes = sourceFont.FontType == Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFontType.Type0 ? 2 : 1;
            Vintasoft.Imaging.Pdf.Content.TextExtraction.PdfTextSymbol[] newSymbols = null;
            // create font subset
            Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont pdfFontSubset = document.FontManager.CreateFontSubset(
                sourceFont,
                necessarySymbols.ToArray(),
                symbolCodeSizeInBytes,
                true,
                out newSymbols);
    
            // add PDF page
            Vintasoft.Imaging.Pdf.Tree.PdfPage page = document.Pages.Add(
                Vintasoft.Imaging.PaperSizeKind.A4);
            // open PDF graphics
            using (Vintasoft.Imaging.Pdf.Drawing.PdfGraphics graphics = page.GetGraphics())
            {
                Vintasoft.Imaging.Pdf.Drawing.PdfBrush brush = 
                    new Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.Black);
                System.Drawing.PointF location = new System.Drawing.PointF(30, page.Size.Height - 150);
                // draw text using created font
                graphics.DrawString(text, pdfFontSubset, 18f, brush, location);
            }
            // pack PDF document to the specified location
            document.Pack(pdfFilename);
        }
    }
    
    

    Requirements

    Target Platforms: .NET 8; .NET 7; .NET 6; .NET Framework 4.8, 4.7, 4.6, 4.5, 4.0, 3.5

    See Also